using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using TR0217.ControlEx.Properties;

namespace TR0217.ControlEx
{
    [ToolboxBitmap(typeof(CollapsibleSplitter), "CollapsibleSplitter.bmp")]
    public class CollapsibleSplitter : Splitter
    {
        bool _hover = false;
        Color _hoverColor = SystemColors.GradientInactiveCaption;
        public System.Drawing.Color HoverColor
        {
            get { return _hoverColor; }
            set 
            {
                _hoverColor = value;
                this.Invalidate();
            }
        }

        public event EventHandler CollapsedChanged;

        Control _controlToHide;
        public System.Windows.Forms.Control ControlToHide
        {
            get { return _controlToHide; }
            set 
            {
                if (value != null && value != _controlToHide)
                {
                    value.VisibleChanged += new EventHandler(_controlToHide_VisibleChanged);
                }

                if (_controlToHide != null)
                {
                    _controlToHide.VisibleChanged -= new EventHandler(_controlToHide_VisibleChanged);
                }
                _controlToHide = value;
            }
        }

        void _controlToHide_VisibleChanged(object sender, EventArgs e)
        {
            if (CollapsedChanged != null)
                CollapsedChanged(this, e);
        }

        /// <summary>
        /// The initial state of the Splitter. Set to True if the control to hide is not visible by default
        /// </summary>
        [Description("The initial state of the Splitter. Set to True if the control to hide is not visible by default")]
        public bool Collapsed
        {
            get
            {
                if (_controlToHide != null)
                    return !_controlToHide.Visible;
                else
                    return false;
            }
            set
            {
                if (_controlToHide != null)
                    _controlToHide.Visible = !value;
            }
        }

        Cursor _curLeft = null;
        Cursor _curRight = null;
        Cursor _curUp = null;
        Cursor _curDown = null;
        public CollapsibleSplitter()
        {
            _curLeft = new Cursor(this.GetType(), "SplitterLeft.cur");
            _curRight = new Cursor(this.GetType(), "SplitterRight.cur");
            _curUp = new Cursor(this.GetType(), "SplitterUp.cur");
            _curDown = new Cursor(this.GetType(), "SplitterDown.cur");
        }

        Rectangle _gripRect;
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
            {
                _gripRect = new Rectangle(0, this.Height / 2 - 57, Width, 115);
            }
            else
            {
                _gripRect = new Rectangle(this.Width / 2 - 57, 0, 115, this.Height);
            }
            this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Pen light = new Pen(SystemColors.ControlLightLight, 2);
            light.DashStyle = DashStyle.DashDot;
            light.DashPattern = new Single[] { 1, 1 };
            Pen dark = new Pen(SystemColors.ControlDark, 2);
            dark.DashStyle = DashStyle.DashDot;
            dark.DashPattern = new Single[] { 1, 1 };
            Brush b = new SolidBrush(_hoverColor);

            // Check the docking style and create the control rectangle accordingly
            if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
            {
                if (_hover)
                {
                    e.Graphics.FillRectangle(b, _gripRect);
                }
                int x = _gripRect.Left + _gripRect.Width / 2;
                int y = _gripRect.Top;
                e.Graphics.DrawLine(light, x, y, x, _gripRect.Bottom - 1);
                e.Graphics.DrawLine(dark, x + 1, y + 1, x + 1, _gripRect.Bottom);

            }
            else
            {
                if (_hover)
                {
                    e.Graphics.FillRectangle(b, _gripRect);
                }
                int x = _gripRect.Left;
                int y = _gripRect.Top + _gripRect.Height / 2;
                e.Graphics.DrawLine(light, x, y, _gripRect.Right-1, y);
                e.Graphics.DrawLine(dark, x + 1, y + 1, _gripRect.Right,y + 1);
            }
            b.Dispose();
            light.Dispose();
            dark.Dispose();
        }


        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (_gripRect.Contains(e.Location))
            {
                _hover = true;
                switch (base.Dock)
                {
                    case DockStyle.Left:
                        base.Cursor = this.Collapsed ? _curRight : _curLeft;
                        break;
                    case DockStyle.Right:
                        base.Cursor = this.Collapsed ? _curLeft : _curRight;
                        break;
                    case DockStyle.Top:
                        base.Cursor = this.Collapsed ? _curDown : _curUp;
                        break;
                    case DockStyle.Bottom:
                        base.Cursor = this.Collapsed ? _curUp : _curDown;
                        break;
                    default:
                        base.Cursor = Cursors.Default;
                        break;
                }
            }
            else
            {
                _hover = false;
                if (this.Collapsed || _moueDownInGrip)
                {
                    base.Cursor = Cursors.Default;
                }
                else if (base.Dock == DockStyle.Left || base.Dock == DockStyle.Right)
                {
                    base.Cursor = Cursors.VSplit;
                }
                else
                {
                    base.Cursor = Cursors.HSplit;
                }
            }
            this.Invalidate(_gripRect);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            _hover = false;
            this.Invalidate();
        }

        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            if (_controlToHide != null && _moueDownInGrip && _hover)
            {
                this.Collapsed = _controlToHide.Visible;
            }            
        }

        bool _moueDownInGrip = false;
        protected override void OnMouseDown(MouseEventArgs e)
        {
            // if the hider control isn't hot, let the base resize action occur

            if (_gripRect.Contains(e.Location))
            {
                _moueDownInGrip = true;
            }
            else //if (!_hover)
            {
                if (_controlToHide != null && _controlToHide.Visible)
                {
                    base.OnMouseDown(e);
                }               
            }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            _moueDownInGrip = false;
        }

    }
}
